﻿using System;
using System.Globalization;
using log4net;
using Matrix.MaKaYunShang.BLL;
using Matrix.MaKaYunShang.Model;
using Matrix.MaKaYunShang.Model.MatrixCloudApi;

namespace Matrix.MaKaYunShang.WeChat.CardProccess
{
    public class MemberCardProccess : BaseWechatCardProcess
    {
        private readonly ILog _fileLog = LogManager.GetLogger(typeof(MemberCardProccess));
        private readonly WeChatMemberCardBLL _weChatMemberCardBll = new WeChatMemberCardBLL();
        private readonly WeChatMemberCardCodeBLL _weChatMemberCardCodeBll = new WeChatMemberCardCodeBLL();

        private WeChatMemberCard _weChatMemberCard;
        private WechatInfo _wechatInfo;

        public MemberCardProccess(string cardId, WechatInfo wechatInfo)
        {
            if (wechatInfo == null || wechatInfo.Id == 0 || string.IsNullOrWhiteSpace(wechatInfo.Secret) ||
                string.IsNullOrWhiteSpace(wechatInfo.AppId))
            {
                throw new Exception("The wechat info is invalid");
            }
            _wechatInfo = wechatInfo;

            if (string.IsNullOrWhiteSpace(cardId))
            {
                throw new Exception("The card id is empty");
            }

            _weChatMemberCard = WeChatMemberCardBLL.Instance.GetModelByCardId(cardId);
            if (_weChatMemberCard == null || _weChatMemberCard.Id == 0)
            {
                _weChatMemberCard = ReGetWeChatCardInfoFromWeChat(cardId);
                if (_weChatMemberCard == null || _weChatMemberCard.Id == 0)
                {
                    throw new Exception("Cannot get the wechat member card info from local database.");
                }
            }
        }

        

        /// <summary>
        /// 审核事件
        /// </summary>
        /// <param name="eventHistory"></param>
        /// <param name="cardStatus"></param>
        public override void CardAuditEvent(MxApiWechatEventHistory eventHistory, WechatCommonCardStatus cardStatus)
        {
            try
            {
                var dtCreateTime =
                WxInterCardFuncObj.FormatToTime(eventHistory.CreateTime.ToString(CultureInfo.InvariantCulture));
                if (dtCreateTime != null)
                {
                    _weChatMemberCard.VerifyTime = (DateTime)dtCreateTime;
                }
                else
                {
                    _weChatMemberCard.VerifyTime = DateTime.Now;
                }
                _weChatMemberCardBll.Update(_weChatMemberCard);

#if DEBUG
                _fileLog.Info(
                    "MemberCardProccess | CardAuditEvent | Finished to  audit card. CardId - " + eventHistory.CardId);
#endif
            }
            catch (Exception ex)
            {
                _fileLog.Error(
                    "MemberCardProccess | CardAuditEvent | Cannot audit card. CardId - " + eventHistory.CardId  +
                    ex.Message + ex.StackTrace);
            }
        }

        /// <summary>
        /// 用户领取事件
        /// </summary>
        /// <param name="eventHistory"></param>
        public override void CustomerGetCardEvent(MxApiWechatEventHistory eventHistory)
        {
            try
            {
                var checkCode = _weChatMemberCardCodeBll.GetModelByCardIdCode(eventHistory.CardId,
                    eventHistory.UserCardCode);
                if (checkCode != null && checkCode.Id > 0)
                {
                    _fileLog.Info("MemberCardProccess | CustomerGetCardEvent - Code Existed | CardId -" + _weChatMemberCard.CardId +
                                  " | UserCardCode -" + eventHistory.UserCardCode);
                    return;
                }
                //新领取卡券信息原则：如果微信服务端未能成功获取会员信息，默认该卡券被用户成功获取
                var wxMemberCardUserInfoForGet = GetWxMCardMInfoUserInfo(_weChatMemberCard.CardId, eventHistory.UserCardCode,
                    eventHistory.FromUserName);

                //构建新的卡券码对象
                var cardCodeInfo = new WeChatMemberCardCode
                {
                    AddTime = DateTime.Now,
                    CardId = _weChatMemberCard.CardId,
                    CardCode = eventHistory.UserCardCode,
                    FriendUserOpenId = eventHistory.FriendUserName,
                    IsGiveByFriend = eventHistory.IsGiveByFriend,
                    OuterId = eventHistory.OuterId,
                    OldUserCardCode = eventHistory.OldUserCardCode,
                    WeChatMemberCardId = _weChatMemberCard.Id,
                    OpenId = eventHistory.FromUserName,
                    CardGetTime =
                        WxInterCardFuncObj.FormatToTime(eventHistory.CreateTime.ToString(CultureInfo.InvariantCulture)) ??
                        DateTime.Now,
                    UserCardStatus =
                        (string.IsNullOrWhiteSpace(wxMemberCardUserInfoForGet.user_card_status))
                            ? wxMemberCardUserInfoForGet.user_card_status
                            : WechatCommonCardCodeStatus.NORMAL.ToString()
                };

                //添加卡券对应的会员信息
                if (!string.IsNullOrWhiteSpace(wxMemberCardUserInfoForGet.openid))
                {
                    cardCodeInfo.NickName = wxMemberCardUserInfoForGet.nickname;
                    cardCodeInfo.Bonus = wxMemberCardUserInfoForGet.bonus;
                    cardCodeInfo.Balance = wxMemberCardUserInfoForGet.balance;
                    cardCodeInfo.Sex = wxMemberCardUserInfoForGet.sex;
                    if (wxMemberCardUserInfoForGet.user_info != null &&
                        wxMemberCardUserInfoForGet.user_info.custom_field_list != null)
                    {
                        foreach (var customfield in wxMemberCardUserInfoForGet.user_info.custom_field_list)
                        {
                            switch (customfield.name.ToUpper())
                            {
                                case "USER_FORM_INFO_FLAG_MOBILE":
                                    cardCodeInfo.Mobile = customfield.value;
                                    break;
                                case "USER_FORM_INFO_FLAG_NAME":
                                    cardCodeInfo.RealName = customfield.value;
                                    break;
                                case "USER_FORM_INFO_FLAG_BIRTHDAY":
                                    cardCodeInfo.Birthday = customfield.value;
                                    break;
                                case "USER_FORM_INFO_FLAG_IDCARD":
                                    cardCodeInfo.IdCard = customfield.value;
                                    break;
                                case "USER_FORM_INFO_FLAG_EMAIL":
                                    cardCodeInfo.Email = customfield.value;
                                    break;
                                case "USER_FORM_INFO_FLAG_DETAIL_LOCATION":
                                    cardCodeInfo.DetailLocation = customfield.value;
                                    break;
                                case "USER_FORM_INFO_FLAG_EDUCATION_BACKGROUND ":
                                    cardCodeInfo.EducationBackground = customfield.value;
                                    break;
                                case "USER_FORM_INFO_FLAG_CAREER":
                                    cardCodeInfo.Career = customfield.value;
                                    break;
                                case "USER_FORM_INFO_FLAG_INDUSTRY":
                                    cardCodeInfo.Industry = customfield.value;
                                    break;
                                case "USER_FORM_INFO_FLAG_INCOME":
                                    cardCodeInfo.Income = customfield.value;
                                    break;
                                case "USER_FORM_INFO_FLAG_HABIT":
                                    cardCodeInfo.Habit = customfield.value;
                                    break;
                            }
                        }
                    }
                }

                _weChatMemberCardCodeBll.Add(cardCodeInfo);
#if DEBUG
                _fileLog.Info("MemberCardProccess | CustomerGetCardEvent - Finish add new card code to database | CardId -" +
                                      _weChatMemberCard.CardId + " | OldUserCardCode -" + eventHistory.OldUserCardCode +
                                      " | UserCardCode -" + eventHistory.UserCardCode);
#endif

                #region 转赠处理
                if (eventHistory.IsGiveByFriend == 1)
                {
                    var originalCode = _weChatMemberCardCodeBll.GetModelByCardIdCode(_weChatMemberCard.CardId,
                        eventHistory.OldUserCardCode);
                    if (originalCode == null || originalCode.Id == 0)
                    {
                        _fileLog.Error("MemberCardProccess | CustomerGetCardEvent - Code for giving is not Existed | CardId -" +
                                      _weChatMemberCard.CardId + " | OldUserCardCode -" + eventHistory.OldUserCardCode +
                                      " | UserCardCode -" + eventHistory.UserCardCode);
                        return;
                    }
                    originalCode.UpdateTime = DateTime.Now;
                    originalCode.UserCardStatus = LuckWxCardCodeLocalStatus.Given.ToString();
                    _weChatMemberCardCodeBll.Update(originalCode);
                }
                #endregion
            }
            catch (Exception ex)
            {
                _fileLog.Error(
                    "MemberCardProccess | CustomerGetCardEvent | Failed to add new card code to database - " +
                    ex.Message + ex.StackTrace);
            }
        }

        /// <summary>
        /// 用户删除事件
        /// </summary>
        /// <param name="eventHistory"></param>
        public override void UserDeleteCardEvent(MxApiWechatEventHistory eventHistory)
        {
            try
            {
                var checkCode = _weChatMemberCardCodeBll.GetModelByCardIdCode(eventHistory.CardId,
                    eventHistory.UserCardCode);
                if (checkCode == null || checkCode.Id == 0)
                {
                    _fileLog.Error("MemberCardProccess | UserDeleteCardEvent - Code is not existed | CardId -" + eventHistory.CardId +
                                  " | UserCardCode -" + eventHistory.UserCardCode);
                    return;
                }

                if (checkCode.OpenId != eventHistory.FromUserName)
                {
                    _fileLog.Info("MemberCardProccess | UserDeleteCardEvent - Invalid open id | CardId -" + eventHistory.CardId +
                                  " | OpenId - " + eventHistory.FromUserName + " | UserCardCode -" +
                                  eventHistory.UserCardCode);
                    return;
                }

                checkCode.UserCardStatus = LuckWxCardCodeLocalStatus.Delete.ToString();
                var dtDeleteTime =
                    WxInterCardFuncObj.FormatToTime(eventHistory.CreateTime.ToString(CultureInfo.InvariantCulture));
                checkCode.UpdateTime = dtDeleteTime ?? DateTime.Now;
                checkCode.IsDelete = true;
                _weChatMemberCardCodeBll.Update(checkCode);
            }
            catch (Exception ex)
            {
                _fileLog.Error(
                    "MemberCardProccess | UserDeleteCardEvent | Failed to delete card code to database - " +
                    ex.Message + ex.StackTrace);
            }
        }

        /// <summary>
        /// 获取用户信息
        /// </summary>
        /// <param name="cardId"></param>
        /// <param name="cardCode"></param>
        /// <param name="eventOpenId"></param>
        /// <returns></returns>
        private WeChatMemberCardMemberInfo GetWxMCardMInfoUserInfo(string cardId, string cardCode, string eventOpenId)
        {
            var wxMemberCardUserInfo = new WeChatMemberCardMemberInfo();
            var strAccessToken = WxInterCardFuncObj.GetWxToken(_wechatInfo.AppId, _wechatInfo.Secret, _wechatInfo.WechatId);
            if (!string.IsNullOrWhiteSpace(strAccessToken))
            {

                _fileLog.Info(
                 "MemberCardProccess | GetWxMCardMInfoUserInfo | cardCode :" +
                 cardCode + "cardId:" + cardId + ",WechatId=" + _wechatInfo.WechatId + ",strAccessToken=" + strAccessToken);
                wxMemberCardUserInfo = WxInterCardFuncObj.GetMemberCardUserInfo(strAccessToken, cardId, cardCode);
                if (wxMemberCardUserInfo != null && wxMemberCardUserInfo.openid != eventOpenId)
                {
                    _fileLog.Error(
                        "MemberCardProccess | CustomerGetCardEvent | The openid of event is not same with card user info of Wechat server - Event openid :" +
                        eventOpenId + " server open id:" + wxMemberCardUserInfo.openid + ",errmsg:" + wxMemberCardUserInfo.errmsg);
                    return null;
                }
            }
            return wxMemberCardUserInfo;
        }

        /// <summary>
        /// 获取卡券信息，若本地无则从微信端重新获取一次，再保存到本地
        /// </summary>
        /// <param name="cardId"></param>
        /// <returns></returns>
        private WeChatMemberCard ReGetWeChatCardInfoFromWeChat(string cardId)
        {
#if DEBUG
            _fileLog.Info(
                "MemberCardProccess | ReGetWeChatCardInfoFromWeChat | Need to re-get the card infomation from wechat server. CardId - " +
                cardId);
#endif

            try
            {
                var cardInfoFromWx = GetCardInfoByCardIdFromWechat(cardId, _wechatInfo);
                if (cardInfoFromWx == null || string.IsNullOrWhiteSpace(cardInfoFromWx.card_id))
                {
                    return null;
                }

                var cardInfo = WxInterCardFuncObj.ConvertWxMemberCardToDbWxMemberCard(cardInfoFromWx);
                var nAddCardRet = _weChatMemberCardBll.Add(cardInfo);
                if (nAddCardRet > 0)
                {
                    cardInfo.Id = nAddCardRet;
                    return cardInfo;
                }
                _fileLog.Error(
                    "MemberCardProccess | ReGetWeChatCardInfoFromWeChat | Failed to create local card info data to db. CardId - " +
                    cardId);
                return null;
            }
            catch (Exception ex)
            {
                _fileLog.Error(
                    "MemberCardProccess | ReGetWeChatCardInfoFromWeChat | Cannot get card info from Wechat server - " +
                    ex.Message + ex.StackTrace);
                return null;
            }
        }
    }
}